package dkbta.ontology.values;

import dkbta.ontology.Ontology;
import dkbta.ontology.elements.Element;
import dkbta.ontology.elements.ElementDef;
import dkbta.ontology.elements.ElementType;
import dkbta.ontology.loading.OntologyException;

/**
 * A value condition that operates on an element's own value
 * 
 * @author Uri Kanonov
 */
public class ElementValueCondition extends ValueCondition{

	/**
	 * Constructs a non-event based constraint with the given primitive
	 * 
	 * @param elementName The name of the element the constraint is based on
	 * @param possibleValues The possible values the constraint allows
	 */
	public ElementValueCondition(String elementName, ElementType elementType,
		Values possibleValues){
		super(elementName, elementType, possibleValues);
	}

	@Override
	public void validate(Ontology ontology) throws OntologyException{
		// Making sure the constraint's value type and the element value type match
		ElementDef element = ontology.getElement(_elementType, _elementName);
		if (element == null){
			throw new OntologyException(
					"The value constraint operates on a non-existing " + _elementType
							+ ": " + _elementName);
		}
		if (_allowedValues != null){
			Values elementValues = element.getValues();
			ValuesType elementValType = elementValues == null ? null : elementValues.getValueType();
			ValuesType constraintValType = _allowedValues.getValueType();

			if (elementValType != constraintValType){
				throw new OntologyException("Value constraint of type "
						+ constraintValType + " on the " + _elementType + " "
						+ _elementName + " with value type " + elementValType);
			}

			if (!elementValues.contains(_allowedValues)){
				throw new OntologyException("The constraint's values '" + _allowedValues
						+ "' are not contained in the values of " + _elementName + " '"
						+ elementValues + "'");
			}
		}
	}

	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append(_elementType).append(" - ").append(_elementName);
		sb.append(", ");
		sb.append(_allowedValues);
		return sb.toString();
	}

	@Override
	public boolean checkCondition(Element e){
		return _allowedValues == null ? true : _allowedValues.isValid(e.getValueType(), e
				.getValue());
	}
}
